package com.mj.haier.calc.service;

import com.mj.haier.calc.domain.AzEncourage;
import com.mj.haier.calc.domain.AzEncourageCash;
import com.mj.haier.calc.domain.BdGvsItemconfig;
import com.mj.haier.calc.domain.CarsInfo;
import com.mj.haier.calc.domain.CarsTeamInfo;
import com.mj.haier.calc.repository.AzEncourageCashRepository;
import com.mj.haier.calc.repository.AzEncourageRepository;
import com.mj.haier.calc.sharding.generator.ShardingKeyGenerator;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.mj.haier.calc.client.FinClient;
import com.mj.haier.calc.client.RrskxClient;

import java.math.BigDecimal;
import java.time.Instant;
import java.util.*;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import static com.google.common.base.Preconditions.checkArgument;

@Service
@Transactional
public class AzEncourageService {

    private final Logger log = LoggerFactory.getLogger(AzEncourageService.class);

    @Autowired
    private RrskxClient rrskxClient;
    @Autowired
    private FinClient finClient;
    @PersistenceContext
    private EntityManager entityManager;
    @Autowired
    private AzEncourageCashRepository azEncourageCashRepository;
    @Autowired
    private AzEncourageRepository azEncourageRepository;

    /**
     * 创建安装单激励与激励兑现明细
     *
     * @param azEncourage
     * @return
     * @throws Exception
     */
    public AzEncourage createAzEncourageAndCash(AzEncourage azEncourage) throws RuntimeException{

        // [encourageImportDate]激励录入时间必须, 格式为UTC标准")
        checkArgument(null != azEncourage.getEncourageImportDate(), "[encourageImportDate]激励录入时间必须, 格式为UTC标准!");

        //验证车队， 产业编码，
        String netpoint = azEncourage.getEncourageObject();
        List<CarsTeamInfo> list = rrskxClient.searchCarsTeamInfosByNetpoint(netpoint);
        checkArgument(list.size() != 0, "当前[%s]查不到有效的网点信息！", netpoint);

        azEncourage.netpoint(netpoint).encourageObject(list.get(0).getCarsTeamId());
        BdGvsItemconfig itemconfig = finClient.getBdGvsItemconfig(azEncourage.getSourceNameCode());
        checkArgument(StringUtils.isNotBlank(itemconfig.getDepartment()), "当前[%s]查不到有效的末级小微关联，请维护！", itemconfig.getDepartment());

        //如果 proportion > 0, 验证车辆信息
        Integer proportion = azEncourage.getProportion();
        BigDecimal encourageAmount = new BigDecimal(azEncourage.getEncourageAmounts());
        BigDecimal encourageSecondAmount = new BigDecimal("0");
        if(proportion > 0){
            String encourageSecondObject = azEncourage.getEncourageSecondObject();
            checkArgument(StringUtils.isNotBlank(encourageSecondObject), "当前[proportion] > 0 时，第二激励对象不能为空！");
            CarsInfo carsInfo = rrskxClient.getCarsInfo(encourageSecondObject);
            checkArgument(StringUtils.isNotBlank(carsInfo.getCarsId()), "当前[proportion] > 0 时，第二激励对象查询不到车辆或服务兵对象！");
            encourageSecondAmount = encourageAmount.multiply(new BigDecimal(proportion)).divide(new BigDecimal("100"), BigDecimal.ROUND_HALF_UP, 2);
            encourageAmount = encourageAmount.subtract(encourageSecondAmount);
        }

        //生成新AzEncourage， AzEncourageCash, 车队 1， 车辆 0
        Long keyGenerator = ShardingKeyGenerator.keyGenerator().longValue();
        azEncourage.id(keyGenerator).settleState("0").secondSettleState("0").gmtCreate(Instant.now()).createUser("createAzEncourageAndCash func");
        entityManager.persist(azEncourage);

        //车队激励兑现明细
        AzEncourageCash carsteamCash = new AzEncourageCash()
            .id(keyGenerator + 1)
            .parentId(keyGenerator)
            .settleBatchId("0")
            .encourageId(azEncourage.getEncourageId())
            .encourageObject(azEncourage.getEncourageObject())
            .payCash("0")
            .outstanding(encourageAmount.toPlainString())
            .incentiveToCdk("0")
            .encourageBudget(azEncourage.getEncourageBudget())
            .sourceSystem(azEncourage.getSourceSystem())
            .sourceNameCode(azEncourage.getSourceNameCode())
            .gmtCreate(Instant.now()).createUser("createAzEncourageAndCash func");
        entityManager.persist(carsteamCash);

        // 如果 encourageSecondAmount 不等于 0, 保存车辆或服务兵
        if(encourageSecondAmount.compareTo(new BigDecimal("0")) != 0){
            AzEncourageCash carsCash = new AzEncourageCash()
                .id(keyGenerator + 0)
                .parentId(keyGenerator)
                .settleBatchId("0")
                .encourageId(azEncourage.getEncourageId())
                .encourageSecondObject(azEncourage.getEncourageSecondObject())
                .payCash("0")
                .outstanding(encourageSecondAmount.toPlainString())
                .incentiveToCdk("0")
                .encourageBudget(azEncourage.getEncourageBudget())
                .sourceSystem(azEncourage.getSourceSystem())
                .sourceNameCode(azEncourage.getSourceNameCode())
                .gmtCreate(Instant.now()).createUser("createAzEncourageAndCash func");
            entityManager.persist(carsCash);
        }
        entityManager.flush();
        entityManager.clear();
        return azEncourage;
    }


    /**
     * 更新安装单激励与激励兑现明细
     *
     * @param azEncourage
     * @return
     */
    public AzEncourage updateAzEncourageAndCash(AzEncourage azEncourage) throws RuntimeException{

        // 当前激励状态不为 0， 不允许更新
        Optional<AzEncourage> oldAzEncourage = azEncourageRepository.findById(azEncourage.getId());
        checkArgument(oldAzEncourage.isPresent(), "当前[%s]下找不到对应激励信息!", azEncourage.getId());

        String settleState = oldAzEncourage.get().getSettleState();
        String secondSettleState = oldAzEncourage.get().getSecondSettleState();
        checkArgument("0".equals(settleState)&&"0".equals(secondSettleState), "当前[%s]下找不到激励信息兑现状态不为未兑现， 不允许更新!", azEncourage.getId());

         // [encourageImportDate]激励录入时间必须, 格式为UTC标准")
         checkArgument(null != azEncourage.getEncourageImportDate(), "[encourageImportDate]激励录入时间必须, 格式为UTC标准!");

         //验证车队， 产业编码，
         String netpoint = azEncourage.getEncourageObject();
         List<CarsTeamInfo> list = rrskxClient.searchCarsTeamInfosByNetpoint(netpoint);
         checkArgument(list.size() != 0, "当前[%s]查不到有效的网点信息！", netpoint);
 
         azEncourage.netpoint(netpoint).encourageObject(list.get(0).getCarsTeamId());
         BdGvsItemconfig itemconfig = finClient.getBdGvsItemconfig(azEncourage.getSourceNameCode());
         checkArgument(StringUtils.isNotBlank(itemconfig.getDepartment()), "当前[%s]查不到有效的末级小微关联，请维护！", itemconfig.getDepartment());
 
         //如果 proportion > 0, 验证车辆信息
         Integer proportion = azEncourage.getProportion();
         BigDecimal encourageAmount = new BigDecimal(azEncourage.getEncourageAmounts());
         BigDecimal encourageSecondAmount = new BigDecimal("0");
         if(proportion > 0){
             String encourageSecondObject = azEncourage.getEncourageSecondObject();
             checkArgument(StringUtils.isNotBlank(encourageSecondObject), "当前[proportion] > 0 时，第二激励对象不能为空！");
             CarsInfo carsInfo = rrskxClient.getCarsInfo(encourageSecondObject);
             checkArgument(StringUtils.isNotBlank(carsInfo.getCarsId()), "当前[proportion] > 0 时，第二激励对象查询不到车辆或服务兵对象！");
             encourageSecondAmount = encourageAmount.multiply(new BigDecimal(proportion)).divide(new BigDecimal("100"), BigDecimal.ROUND_HALF_UP, 2);
             encourageAmount = encourageAmount.subtract(encourageSecondAmount);
         }
 
        //更新AzEncourage， AzEncourageCash, 车队 1， 车辆 0
        azEncourage.settleState("0").secondSettleState("0").gmtCreate(Instant.now()).createUser("updateAzEncourageAndCash func");
        AzEncourage result = azEncourageRepository.save(azEncourage);

        //删除存在的明细
        azEncourageCashRepository.deleteByParentId(azEncourage.getId());
        //重新生成车队激励兑现明细
        AzEncourageCash carsteamCash = new AzEncourageCash()
            .id(azEncourage.getId() + 1)
            .parentId(azEncourage.getId())
            .settleBatchId("0")
            .encourageId(azEncourage.getEncourageId())
            .encourageObject(azEncourage.getEncourageObject())
            .payCash("0")
            .outstanding(encourageAmount.toPlainString())
            .incentiveToCdk("0")
            .encourageBudget(azEncourage.getEncourageBudget())
            .sourceSystem(azEncourage.getSourceSystem())
            .sourceNameCode(azEncourage.getSourceNameCode())
            .gmtCreate(Instant.now()).createUser("updateAzEncourageAndCash func");
        azEncourageCashRepository.save(carsteamCash);

        // 如果 encourageSecondAmount 不等于 0, 重新生成车辆或服务兵
        if(encourageSecondAmount.compareTo(new BigDecimal("0")) != 0){
            AzEncourageCash carsCash = new AzEncourageCash()
                .id(azEncourage.getId() + 0)
                .parentId(azEncourage.getId())
                .settleBatchId("0")
                .encourageId(azEncourage.getEncourageId())
                .encourageSecondObject(azEncourage.getEncourageSecondObject())
                .payCash("0")
                .outstanding(encourageSecondAmount.toPlainString())
                .incentiveToCdk("0")
                .encourageBudget(azEncourage.getEncourageBudget())
                .sourceSystem(azEncourage.getSourceSystem())
                .sourceNameCode(azEncourage.getSourceNameCode())
                .gmtCreate(Instant.now()).createUser("updateAzEncourageAndCash func");
            azEncourageCashRepository.save(carsCash);
        }
        return result;
    }

    /**
     * 删除安装单激励信息
     *
     * @param id
     */
    public void deleteAzEncourageAndCash(long id){
        azEncourageRepository.deleteById(id);
        azEncourageCashRepository.deleteByParentId(id);
    }
}
